package org.dizena.config;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.hibernate.validator.HibernateValidator;
import org.jetbrains.annotations.NotNull;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.util.unit.DataSize;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.servlet.MultipartConfigElement;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import java.util.List;

@Configuration
public class WebConfig implements WebMvcConfigurer
{
    @Bean
    public RestTemplate restTemplate()
    {
        return new RestTemplate();
    }

    /**
     * JSON数据防止Long失真
     */
    @Bean
    public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder)
    {
        ObjectMapper objectMapper = builder.createXmlMapper(false).build();
        // 忽略value为null 时 key的输出
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        SimpleModule module = new SimpleModule();
        //module.addSerializer(Long.class, ToStringSerializer.instance);
        //module.addSerializer(Long.TYPE, ToStringSerializer.instance);
        // module.addSerializer(long.TYPE, ToStringSerializer.instance);
        objectMapper.registerModule(module);
        return objectMapper;
    }

    /**
     * String类型JSON序列化错误解决
     */
    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters)
    {
        converters.removeIf(x -> x instanceof StringHttpMessageConverter);
    }

    /**
     * 跨域请求配置
     */
    @Override
    public void addCorsMappings(CorsRegistry registry)
    {
        registry
                // 设置允许跨域的路径
                .addMapping("/api/**")
                // 设置允许跨域请求的域名
                .allowedOrigins("*")
                // 设置允许header
                .allowedHeaders("*")
                // 设置允许的方法
                .allowedMethods("*")
                // 这里：是否允许证书
                .allowCredentials(true)
                // 跨域允许时间
                .maxAge(3600);
    }

    /**
     * 配置Spring自动校验-规则
     */
    @Bean
    public Validator validator()
    {
        ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class).configure()
                //failFast的意思只要出现校验失败的情况，就立即结束校验，不再进行后续的校验。
                .failFast(true).buildValidatorFactory();
        return validatorFactory.getValidator();
    }

    /**
     * 配置Spring自动校验
     */
    @Bean
    public MethodValidationPostProcessor methodValidationPostProcessor()
    {
        MethodValidationPostProcessor methodValidationPostProcessor = new MethodValidationPostProcessor();
        methodValidationPostProcessor.setValidator(validator());
        return methodValidationPostProcessor;
    }

    @Bean
    public MultipartConfigElement multipartConfigElement()
    {
        MultipartConfigFactory factory = new MultipartConfigFactory();
        factory.setMaxRequestSize(DataSize.ofGigabytes(5));
        factory.setMaxFileSize(DataSize.ofGigabytes(5));
        return factory.createMultipartConfig();
    }

}